package com.yellowcong.config;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.filter.DelegatingFilterProxy;

import com.yellowcong.filter.JwtFilter;
import com.yellowcong.realm.JwtRealm;

@Configuration
@PropertySource("classpath:shiro.properties")  // 指定读取的配置文件地址
public class ShiroConfig {
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
        filterRegistration.setFilter(new DelegatingFilterProxy("shiroFilter"));
        filterRegistration.addInitParameter("targetFilterLifecycle", "true");
        filterRegistration.setEnabled(true);
        filterRegistration.addUrlPatterns("/*");
        return filterRegistration;
    }

    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
        daap.setProxyTargetClass(true);
        return daap;
    }

    @Bean
    public JwtRealm getSampleRealm(){
    	return new JwtRealm();
    }

    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //设定realm 用于权限的认证
        securityManager.setRealm(this.getSampleRealm());
        //用于securityManager 的缓存
        securityManager.setCacheManager(new MemoryConstrainedCacheManager());
       
        //关闭shiro自带的session 
        //参考文档
        //http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator evaluator = new DefaultSessionStorageEvaluator();
        evaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(evaluator);
        securityManager.setSubjectDAO(subjectDAO);
        return securityManager;
    }
    
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    /**
     * shiro的过滤器
     * @param securityManager
     * @param casFilter
     * @param casServerUrlPrefix
     * @param shiroServerUrlPrefix
     * @return
     */
    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager,
    		@Value("${shiro.loginUrl}") String loginUrl,  //登陆地址
    		@Value("${shiro.successUrl}") String successUrl, //登陆成功地址
    		@Value("${shiro.unauthorizedUrl}") String unauthorizedUrl) {  //未授权的地址 
    	ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    	
    	//设定认证管理的Manager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        
        //设定登陆地址
        shiroFilterFactoryBean.setLoginUrl(loginUrl);
        
        //设定登陆成功跳转的地址
        shiroFilterFactoryBean.setSuccessUrl(successUrl);
        //设定未授权的地址
        shiroFilterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);
        
        
        // 添加自己的过滤器并且取名为jwt
        Map<String, Filter> filterMap = new HashMap<>(1);
        filterMap.put("jwt", new JwtFilter());
        shiroFilterFactoryBean.setFilters(filterMap);
        
        
        
        Map<String,String> chainMap = new LinkedHashMap<>();
        chainMap.put("/user/login", "anon");        //登陆界面任何人可以访问
        chainMap.put("/error", "anon");             // erro的信息
        chainMap.put("/user/unauthorized", "anon");             // erro的信息
        chainMap.put("/resources/img/**", "anon");  //图片样式可以直接访问
        chainMap.put("/resources/js/**", "anon");   //js可以直接访问
        chainMap.put("/favicon.ico", "anon");   //js可以直接访问
        chainMap.put("/user/list", "jwt");        //用户列表需要授权
        
        //设定授权方式为jwt
        chainMap.put("/**", "jwt");   // 余下的页面，全都需要进行授权操作
        shiroFilterFactoryBean.setFilterChainDefinitionMap(chainMap);
        
        return shiroFilterFactoryBean;
    }

}  